#pragma once

#include <unistd.h>
#include "Data.hpp"

extern cloud::DataManager *data_;

namespace cloud
{
    // 热点文件管理类
    class HotManager
    {
    private:
        std::string pack_dir_;    // 压缩包路径
        std::string backup_dir_;  // 文件实际存储路径
        std::string pack_suffix_; // 压缩包文件后缀
        int hot_time_;            // 热点时间

    private:
        // 判断文件是否是热点文件的函数：热点文件返回true，否则返回false
        bool HotFileJudge(const std::string &filename)
        {
            FileUtil fu(filename);
            time_t last_visitTime = fu.LastVisitTime();
            time_t curTime = time(nullptr);
            // 时间超过 hot_time_ 就是一个非热点文件
            if (curTime - last_visitTime > hot_time_)
                return false;

            return true;
        }

    public:
        HotManager()
        {
            Config *config = Config::GetInstance();
            pack_dir_ = config->GetPackDir();
            backup_dir_ = config->GetBackDir();
            pack_suffix_ = config->GetPackFileSuffix();
            hot_time_ = config->GetHotTime();

            FileUtil tmp1(backup_dir_);
            tmp1.CreateDirectory();
            FileUtil tmp2(pack_dir_);
            tmp2.CreateDirectory();
        }

        // 判断所有备份文件是否是热点文件，如果不是，就压缩处理
        bool RunModule()
        {
            while (1)
            {
                // 1. 遍历备份文件路径下的所有备份文件，获取文件名
                FileUtil fu(backup_dir_);
                std::vector<std::string> arry;
                fu.ScanDirectory(&arry);
                // 2. 遍历判断这些文件是否是非热点文件
                for (auto &file : arry)
                {
                    // 2.1 是热点文件，就不进行压缩
                    if (HotFileJudge(file))
                    {
                        continue;
                    }

                    BackupInfo bi;
                    if (!data_->GetOneByRealpath(file, &bi))
                    {
                        // 说明有该备份文件，但是没有其相关信息，即无BackupInfo
                        bi.NewBackupInfo(file);
                    }
                    // 3. 对非热点文件进行压缩处理
                    FileUtil tmp(file);
                    tmp.Compress(bi.pack_path);
                    // 4. 删除源文件，修改 backupinfo 中的相关信息
                    tmp.Remove();
                    bi.pack_flag = true;
                    data_->Update(bi);
                }
                usleep(1000);
            }

            return true;
        }
    };
}